﻿using System;
using System.Reflection;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace ADEVSO.Web
{
    public class ImageHandler : IHttpHandler
    {
        private const String defaultImage = "Web.Resources.no_image.png";

        public void ProcessRequest(HttpContext context)
        {
            // Possible parameters passed on query String
            int id = -1, width = -1, height = -1;
            String url = String.Empty;
            String quality = String.Empty;

            byte[] image = null;
            Bitmap photo = null;
            MemoryStream memory = null;

            // Catch parameters througth query String
            try { id = Convert.ToInt32(context.Request.QueryString["id"].ToString()); }
            catch
            {
                try { url = context.Request.QueryString["url"]; }
                catch { }
            }

            // Width parameter
            try { width = Convert.ToInt32(context.Request.QueryString["w"]); }
            catch { }
            // Height parameter
            try { height = Convert.ToInt32(context.Request.QueryString["h"]); }
            catch { }
            // Quality parameter
            try { quality = context.Request.QueryString["q"]; }
            catch { }

            // image will be read from database
            if (id > -1)
            {
                try { image = LoadImage(context); }
                // Set Default image
                catch
                {
                    image = DefaultImage;
                    width = 275;
                    height = 200;
                }
                memory = new MemoryStream(image);
                photo = new Bitmap(memory);
            }
            else
            {
                try
                {
                    // image will be read from url
                    if (!String.IsNullOrEmpty(url))
                    {
                        url = ProccessUrl(url);
                        photo = new Bitmap(context.Server.MapPath(url));
                        memory = new MemoryStream();
                        photo.Save(memory, ImageFormat.Png);
                        image = memory.GetBuffer();
                    }
                }
                catch
                {
                    // Set Default image
                    image = DefaultImage;
                    memory = new MemoryStream(image);
                    photo = new Bitmap(memory);
                    width = 275;
                    height = 200;
                }
            }

            // Resize image if necessary
            bool resized = Drawing.Image.NewSize(ref width, ref height, photo.Width, photo.Height);
            if (resized || !String.IsNullOrEmpty(quality))
            {
                image = Drawing.Image.ResizeImage(image, width, height, quality);
            }

            // Return photo to browser
            context.Response.Clear();
            context.Response.ContentType = "image/png";
            context.Response.OutputStream.Write(image, 0, image.Length);

            // Release objects
            photo.Dispose();
            memory.Dispose();
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Load image from database
        /// </summary>
        /// <param name="context">Http Context</param>
        /// <returns></returns>
        public virtual byte[] LoadImage(HttpContext context)
        {
            return null;
        }

        /// <summary>
        /// Allow user to process url
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public virtual String ProccessUrl(String url)
        {
            return url;
        }
        
        /// <summary>
        /// Default image
        /// </summary>
        private static byte[] DefaultImage
        {
            get
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                String file = String.Format("{0}.{1}", new object[]{assembly.GetName().Name, defaultImage});
                
                Stream stream = assembly.GetManifestResourceStream(file) as Stream;
                byte[] result = new byte[stream.Length];
                stream.Read(result, 0, (int) stream.Length);
                stream.Close();
                return result;
            }
        }
    }
}